<template>
  <div class="chart-container">
    <!-- 图表标题 -->
    <div v-if="title" class="chart-header mb-4">
      <h3 class="text-lg font-semibold text-gray-900 dark:text-gray-100">{{ title }}</h3>
      <p v-if="subtitle" class="text-sm text-gray-600 dark:text-gray-400 mt-1">{{ subtitle }}</p>
    </div>

    <!-- 图表工具栏 -->
    <div v-if="showToolbar" class="chart-toolbar mb-4 flex items-center justify-between">
      <div class="flex items-center space-x-2">
        <slot name="toolbar-left">
          <button
            v-for="tool in toolbarButtons"
            :key="tool.key"
            @click="handleToolbarAction(tool)"
            :class="tool.class"
            class="inline-flex items-center px-3 py-1.5 text-xs font-medium rounded-md transition-colors duration-200"
          >
            <component v-if="tool.icon" :is="tool.icon" class="w-4 h-4 mr-1" />
            {{ tool.label }}
          </button>
        </slot>
      </div>
      <div class="flex items-center space-x-2">
        <slot name="toolbar-right">
          <!-- 图表类型切换 -->
          <select
            v-if="allowTypeChange"
            v-model="currentChartType"
            @change="handleTypeChange"
            class="text-xs border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100"
          >
            <option v-for="type in chartTypes" :key="type.value" :value="type.value">
              {{ type.label }}
            </option>
          </select>
        </slot>
      </div>
    </div>

    <!-- ECharts 图表 -->
    <div class="chart-wrapper" :style="{ height: height }">
      <VChart
        ref="chartRef"
        :option="chartOption"
        :loading="loading"
        :theme="theme"
        :init-options="initOptions"
        :update-options="updateOptions"
        :group="group"
        autoresize
        @click="handleChartClick"
        @dblclick="handleChartDblClick"
        @mouseover="handleChartMouseOver"
        @mouseout="handleChartMouseOut"
        class="chart-canvas"
      />
    </div>

    <!-- 图表说明 -->
    <div v-if="description" class="chart-description mt-4">
      <p class="text-sm text-gray-600 dark:text-gray-400">{{ description }}</p>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, watch, onMounted, nextTick } from 'vue'
import { useThemeStore } from '@/store/theme'
import {
  ArrowPathIcon,
  ArrowDownTrayIcon,
  PhotoIcon,
  DocumentArrowDownIcon
} from '@heroicons/vue/24/outline'

// Props
interface ChartData {
  labels?: string[]
  datasets?: any[]
  series?: any[]
  [key: string]: any
}

interface ToolbarButton {
  key: string
  label: string
  icon?: any
  class?: string
  action?: string
}

interface ChartType {
  value: string
  label: string
}

const props = withDefaults(defineProps<{
  type: 'line' | 'bar' | 'pie' | 'scatter' | 'area' | 'mixed'
  data: ChartData
  title?: string
  subtitle?: string
  description?: string
  height?: string
  loading?: boolean
  showToolbar?: boolean
  allowTypeChange?: boolean
  toolbarButtons?: ToolbarButton[]
  chartTypes?: ChartType[]
  theme?: string
  initOptions?: any
  updateOptions?: any
  group?: string
  grid?: any
  xAxis?: any
  yAxis?: any
  legend?: any
  tooltip?: any
  colors?: string[]
  responsive?: boolean
}>(), {
  type: 'line',
  data: () => ({}),
  height: '400px',
  loading: false,
  showToolbar: true,
  allowTypeChange: true,
  toolbarButtons: () => [
    {
      key: 'refresh',
      label: '刷新',
      icon: ArrowPathIcon,
      class: 'text-blue-600 hover:text-blue-700 hover:bg-blue-50 dark:text-blue-400 dark:hover:bg-blue-900/20'
    },
    {
      key: 'download',
      label: '下载',
      icon: ArrowDownTrayIcon,
      class: 'text-green-600 hover:text-green-700 hover:bg-green-50 dark:text-green-400 dark:hover:bg-green-900/20'
    }
  ],
  chartTypes: () => [
    { value: 'line', label: '折线图' },
    { value: 'bar', label: '柱状图' },
    { value: 'pie', label: '饼图' },
    { value: 'scatter', label: '散点图' }
  ],
  colors: () => [
    '#3B82F6', '#10B981', '#F59E0B', '#EF4444', '#8B5CF6',
    '#06B6D4', '#84CC16', '#F97316', '#EC4899', '#6B7280'
  ],
  responsive: true
})

// Emits
const emit = defineEmits<{
  chartClick: [params: any]
  chartDblClick: [params: any]
  chartMouseOver: [params: any]
  chartMouseOut: [params: any]
  toolbarAction: [action: string]
  typeChange: [type: string]
  refresh: []
}>()

// Stores
const themeStore = useThemeStore()

// Refs
const chartRef = ref()
const currentChartType = ref(props.type)

// Computed
const theme = computed(() => {
  return themeStore.isDark ? 'dark' : 'light'
})

const chartOption = computed(() => {
  const baseOption = {
    color: props.colors,
    grid: props.grid || {
      top: '10%',
      left: '3%',
      right: '4%',
      bottom: '10%',
      containLabel: true
    },
    tooltip: props.tooltip || {
      trigger: 'axis',
      backgroundColor: themeStore.isDark ? 'rgba(0, 0, 0, 0.8)' : 'rgba(255, 255, 255, 0.9)',
      borderColor: themeStore.isDark ? '#374151' : '#E5E7EB',
      textStyle: {
        color: themeStore.isDark ? '#F3F4F6' : '#374151'
      }
    },
    legend: props.legend || {
      top: 0,
      textStyle: {
        color: themeStore.isDark ? '#F3F4F6' : '#374151'
      }
    }
  }

  switch (currentChartType.value) {
    case 'line':
      return {
        ...baseOption,
        xAxis: props.xAxis || {
          type: 'category',
          data: props.data.labels || [],
          axisLine: {
            lineStyle: {
              color: themeStore.isDark ? '#4B5563' : '#D1D5DB'
            }
          },
          axisLabel: {
            color: themeStore.isDark ? '#9CA3AF' : '#6B7280'
          }
        },
        yAxis: props.yAxis || {
          type: 'value',
          axisLine: {
            lineStyle: {
              color: themeStore.isDark ? '#4B5563' : '#D1D5DB'
            }
          },
          axisLabel: {
            color: themeStore.isDark ? '#9CA3AF' : '#6B7280'
          },
          splitLine: {
            lineStyle: {
              color: themeStore.isDark ? '#374151' : '#F3F4F6'
            }
          }
        },
        series: props.data.series || []
      }

    case 'bar':
      return {
        ...baseOption,
        xAxis: props.xAxis || {
          type: 'category',
          data: props.data.labels || [],
          axisLine: {
            lineStyle: {
              color: themeStore.isDark ? '#4B5563' : '#D1D5DB'
            }
          },
          axisLabel: {
            color: themeStore.isDark ? '#9CA3AF' : '#6B7280'
          }
        },
        yAxis: props.yAxis || {
          type: 'value',
          axisLine: {
            lineStyle: {
              color: themeStore.isDark ? '#4B5563' : '#D1D5DB'
            }
          },
          axisLabel: {
            color: themeStore.isDark ? '#9CA3AF' : '#6B7280'
          },
          splitLine: {
            lineStyle: {
              color: themeStore.isDark ? '#374151' : '#F3F4F6'
            }
          }
        },
        series: props.data.series?.map(s => ({ ...s, type: 'bar' })) || []
      }

    case 'pie':
      return {
        ...baseOption,
        series: [{
          type: 'pie',
          radius: ['40%', '70%'],
          center: ['50%', '50%'],
          data: props.data.series?.[0]?.data || [],
          label: {
            color: themeStore.isDark ? '#F3F4F6' : '#374151'
          },
          labelLine: {
            lineStyle: {
              color: themeStore.isDark ? '#6B7280' : '#9CA3AF'
            }
          }
        }]
      }

    case 'scatter':
      return {
        ...baseOption,
        xAxis: props.xAxis || {
          type: 'value',
          axisLine: {
            lineStyle: {
              color: themeStore.isDark ? '#4B5563' : '#D1D5DB'
            }
          },
          axisLabel: {
            color: themeStore.isDark ? '#9CA3AF' : '#6B7280'
          },
          splitLine: {
            lineStyle: {
              color: themeStore.isDark ? '#374151' : '#F3F4F6'
            }
          }
        },
        yAxis: props.yAxis || {
          type: 'value',
          axisLine: {
            lineStyle: {
              color: themeStore.isDark ? '#4B5563' : '#D1D5DB'
            }
          },
          axisLabel: {
            color: themeStore.isDark ? '#9CA3AF' : '#6B7280'
          },
          splitLine: {
            lineStyle: {
              color: themeStore.isDark ? '#374151' : '#F3F4F6'
            }
          }
        },
        series: props.data.series?.map(s => ({ ...s, type: 'scatter' })) || []
      }

    default:
      return baseOption
  }
})

// Methods
const handleChartClick = (params: any) => {
  emit('chartClick', params)
}

const handleChartDblClick = (params: any) => {
  emit('chartDblClick', params)
}

const handleChartMouseOver = (params: any) => {
  emit('chartMouseOver', params)
}

const handleChartMouseOut = (params: any) => {
  emit('chartMouseOut', params)
}

const handleToolbarAction = (tool: ToolbarButton) => {
  if (tool.key === 'refresh') {
    emit('refresh')
  } else if (tool.key === 'download') {
    downloadChart()
  } else {
    emit('toolbarAction', tool.key)
  }
}

const handleTypeChange = () => {
  emit('typeChange', currentChartType.value)
}

const downloadChart = () => {
  if (chartRef.value) {
    const url = chartRef.value.getDataURL({
      type: 'png',
      pixelRatio: 2,
      backgroundColor: themeStore.isDark ? '#1F2937' : '#FFFFFF'
    })
    
    const link = document.createElement('a')
    link.download = `chart-${Date.now()}.png`
    link.href = url
    link.click()
  }
}

const resize = () => {
  nextTick(() => {
    chartRef.value?.resize()
  })
}

// Watch theme changes
watch(() => themeStore.isDark, () => {
  nextTick(() => {
    chartRef.value?.resize()
  })
})

// Expose methods
defineExpose({
  resize,
  downloadChart,
  getChart: () => chartRef.value
})
</script>

<style scoped>
.chart-container {
  @apply bg-white dark:bg-gray-800 rounded-lg shadow-sm p-4;
}

.chart-header {
  @apply border-b border-gray-200 dark:border-gray-700 pb-4;
}

.chart-toolbar {
  @apply border-b border-gray-200 dark:border-gray-700 pb-4;
}

.chart-wrapper {
  @apply w-full relative;
}

.chart-canvas {
  @apply w-full h-full;
}

.chart-description {
  @apply border-t border-gray-200 dark:border-gray-700 pt-4;
}
</style>
